import { ApiReturn, WsClient } from "tsrpc-browser";
import { ServiceType, serviceProto } from './net_proto/protocols/serviceProto';


/**
 * ws 长链 client 使用
 */
class WSClient {
    private wsClient!: WsClient<ServiceType>;

    // 初始化  ws://119.45.7.202:3100
    public async init(wsUrl: string) {
        this.wsClient = new WsClient(serviceProto, {
            'server': wsUrl,
            'json': true
        });

        //
        let ok = await this.wsClient.connect();
        if (!ok.isSucc) {
            console.error('WebSocket connect failed!' + ok.errMsg);
            this.reconnect();
            return Promise.resolve(false);
        }

        // 监听连接状态
        this.listenConnect();

        // await this.wsClient.callApi('Send', { 'session': "sjdhsu", 'content': "sdsd" });
        return Promise.resolve(true);
    }


    // 重连服务器
    private reconnect() {
        let timer = setInterval(async () => {
            const result = await this.wsClient.connect();
            if (result.isSucc) {
                console.log('WebSocket reconnected');
                clearInterval(timer);
                // timer = null;
                this.listenConnect();
            }
        }, 3000);
        return;
    }


    // 监听连接断开重连
    private listenConnect() {
        this.wsClient.flows.postDisconnectFlow.push(v => {
            console.log('WebSocket disconnected');
            this.reconnect();

            return v;
        });

        return;
    }


    // 请求api
    public async callApi<T extends string & keyof ServiceType['api']>(apiName: T, req: ServiceType['api'][T]['req']): Promise<ApiReturn<ServiceType['api'][T]['res']>> {
        return this.wsClient.callApi(apiName, req);
    }


    // 发送消息
    public async sendMsg<T extends string & keyof ServiceType['msg']>(msgName: T, msg: ServiceType['msg'][T]) {
        return this.wsClient.sendMsg(msgName, msg);
    }


    // 监听消息
    public listenMsg<T extends string & keyof ServiceType['msg']>(msgName: T, listener: (msg: ServiceType['msg'][T]) => void) {
        this.wsClient.listenMsg(msgName, listener);
        return;
    }


}
export const ws = new WSClient();
